package com.sumainfor.wx.system.aspect;

import com.sumainfor.common.exception.TCException;
import com.sumainfor.wx.system.annotation.DS;
import com.sumainfor.wx.system.config.DataSourceConst;
import com.sumainfor.wx.system.config.DataSourceContextHolder;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Author Eddy·Chen
 * @Email 835033913@qq.com
 * @Create 2019-06-14 17:36
 */
@Aspect
@Component
@Log4j2
public class DynamicDataSourceAspect implements Ordered {


    /**
     * 切入点
     */
    @Pointcut("execution(* com.sumainfor.wx.system.*.dao.*.*(..))")
    public void dataSourcePointCut() {

    }

    @Around(value = "dataSourcePointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        DS ds = method.isAnnotationPresent(DS.class) ? method.getAnnotation(DS.class)
                : AnnotationUtils.findAnnotation(method.getDeclaringClass(), DS.class);
        if (ds == null) {
            log.info("默认数据源: market");
            DataSourceContextHolder.push(DataSourceConst.DATA_MARKET);
        } else {
            log.info("获取切片方法名为: {}", method.getName());
            String value = ds.value();
            if (StringUtils.isBlank(value)) {
                DataSourceContextHolder.push(DataSourceConst.DATA_MARKET);
            } else {
                switch (ds.value()) {
                    case DataSourceConst.DATA_EPC:
                        DataSourceContextHolder.push(DataSourceConst.DATA_EPC);
                        break;
                    case DataSourceConst.DATA_GMIO:
                        DataSourceContextHolder.push(DataSourceConst.DATA_GMIO);
                        break;
                    case DataSourceConst.DATA_MARKET:
                        DataSourceContextHolder.push(DataSourceConst.DATA_MARKET);
                        break;
                    case DataSourceConst.DATA_TENANT:
                        DataSourceContextHolder.push(DataSourceConst.DATA_TENANT);
                        break;
                    default:
                        throw new TCException("不存在的数据库配置名称");
                }
            }
        }
        try {
            return point.proceed();
        } finally {
            DataSourceContextHolder.poll();
            log.debug("Clean datasource");
        }
    }

    @Override
    public int getOrder() {
        return -100;
    }
}
